package com.lzkj.region.controller;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.lzkj.region.entity.RawDataRegionDto;
import com.lzkj.region.entity.SysRegionDto;
import com.lzkj.region.entity.SysRegionEntity;
import com.lzkj.region.service.SysRegionService;
import com.lzkj.region.utils.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * SysRegionController
 *
 * @author raos
 * @email 991207823@qq.com
 * @date 2022/8/8 0008 14:18
 */
@Slf4j
@RestController
@RequestMapping("sys/region")
public class SysRegionController {

    @Autowired
    private SysRegionService sysRegionService;

    /**
     * 导入排列好的顺序数据
     *
     * @param file
     * @return
     */
    @PostMapping("/importExcel")
    public String importExcel(@RequestParam("file") MultipartFile file) {
        Assert.isTrue(FileUtil.isExcelFile(file) , "请上传Excel文件");
        long startTime = System.currentTimeMillis();
        try {
            ExcelReader excelReader = ExcelUtil.getReader(file.getInputStream());
            // 数据读取位置从标题以第0行开始，数据以第1行开始。索引值以0开始及Excel的第1行的读取行数的下标为0。
            List<SysRegionDto> list = excelReader.read(0, 1, SysRegionDto.class);
            Assert.notEmpty(list, "无数据导入");
            if (list.size() > 1000) {
                int lastPageNum = list.size() % 1000;
                int page = (list.size() / 1000) + (lastPageNum > 0 ? 1 : 0);
                for (int i = 1; i <= page; i++) {
                    int start = (i - 1) * 1000;
                    int end = i * 1000;
                    if (lastPageNum > 0 && i == page) {
                        start = (page - 1) * 1000;
                        end = start + lastPageNum;
                    }
                    List<SysRegionEntity> sysRegionEntityList = new ArrayList<>(1000);
                    for (int j = start; j < end; j ++) {
                        SysRegionDto sysRegionDto = list.get(j);
                        sysRegionEntityList.add(sysRegionDto.gainSysRegionEntity());
                    }
                    sysRegionService.saveBatch(sysRegionEntityList);
                }
            } else {
                List<SysRegionEntity> sysRegionEntityList = new ArrayList<>(list.size());
                list.forEach(sysRegionDto -> sysRegionEntityList.add(sysRegionDto.gainSysRegionEntity()));
                sysRegionService.saveBatch(sysRegionEntityList);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "导入失败,失败信息:" + e.getMessage();
        }
        log.info("导入耗时毫秒数=【{}】", System.currentTimeMillis() - startTime);
        return "导入成功!";
    }

    @PostMapping("/importExcel2")
    public String importExcel2(@RequestParam("file") MultipartFile file) {
        Assert.isTrue(FileUtil.isExcelFile(file) , "请上传Excel文件");
        long startTime = System.currentTimeMillis();
        try {
            ExcelReader excelReader = ExcelUtil.getReader(file.getInputStream());
            // 数据读取位置从标题以第0行开始，数据以第1行开始。索引值以0开始及Excel的第1行的读取行数的下标为0。
            List<RawDataRegionDto> list = excelReader.read(0, 1, RawDataRegionDto.class);
            Assert.notEmpty(list, "无数据导入");
            if (list.size() > 1000) {
                int lastPageNum = list.size() % 1000;
                int page = (list.size() / 1000) + (lastPageNum > 0 ? 1 : 0);
                for (int i = 1; i <= page; i++) {
                    int start = (i - 1) * 1000;
                    int end = i * 1000;
                    if (lastPageNum > 0 && i == page) {
                        start = (page - 1) * 1000;
                        end = start + lastPageNum;
                    }
                    List<SysRegionEntity> sysRegionEntityList = new ArrayList<>(1000);
                    for (int j = start; j < end; j ++) {
                        RawDataRegionDto regionDto = list.get(j);
                        sysRegionEntityList.add(regionDto.gainSysRegionEntity());
                    }
                    sysRegionService.saveBatch(sysRegionEntityList);
                }
            } else {
                List<SysRegionEntity> sysRegionEntityList = new ArrayList<>(list.size());
                list.forEach(sysRegionDto -> sysRegionEntityList.add(sysRegionDto.gainSysRegionEntity()));
                sysRegionService.saveBatch(sysRegionEntityList);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "导入失败,失败信息:" + e.getMessage();
        }
        log.info("导入耗时毫秒数=【{}】", System.currentTimeMillis() - startTime);
        return "导入成功!";
    }

    // 清洗数据
    @RequestMapping("/cleanData")
    public String cleanAssembleData() {
        long startTime = System.currentTimeMillis();
        Map<String, SysRegionEntity> dataMap = new HashMap<>(1000);
        List<SysRegionEntity> list = sysRegionService.list();
        list.forEach(sysRegionEntity -> {
            if (sysRegionEntity.getType() != 5) {
                dataMap.put(sysRegionEntity.getAreaCode(), sysRegionEntity);
            }
        });
        log.info("采集父ID耗时毫秒数=【{}】", System.currentTimeMillis() - startTime);
        list.forEach(sysRegionEntity -> {
            if (sysRegionEntity.getType() == 2) {
                String areaCode = sysRegionEntity.getAreaCode().substring(0, 2);
                updateProperties(dataMap, sysRegionEntity, areaCode);
            } else if (sysRegionEntity.getType() == 3) {
                String areaCode = sysRegionEntity.getAreaCode().substring(0, 4);
                updateProperties(dataMap, sysRegionEntity, areaCode);
            } else if (sysRegionEntity.getType() == 4) {
                String areaCode = sysRegionEntity.getAreaCode().substring(0, 6);
                updateProperties(dataMap, sysRegionEntity, areaCode);
            } else if (sysRegionEntity.getType() == 5) {
                String areaCode = sysRegionEntity.getAreaCode().substring(0, 9);
                updateProperties(dataMap, sysRegionEntity, areaCode);
            }
        });
        log.info("更新属性耗时毫秒数=【{}】", System.currentTimeMillis() - startTime);
        if (list.size() > 1000) {
            int lastPageNum = list.size() % 1000;
            int page = (list.size() / 1000) + (lastPageNum > 0 ? 1 : 0);
            for (int i = 1; i <= page; i++) {
                int start = (i - 1) * 1000;
                int end = i * 1000;
                if (lastPageNum > 0 && i == page) {
                    start = (page - 1) * 1000;
                    end = start + lastPageNum;
                }
                List<SysRegionEntity> sysRegionEntityList = new ArrayList<>(1000);
                for (int j = start; j < end; j ++) {
                    SysRegionEntity regionEntity = list.get(j);
                    sysRegionEntityList.add(regionEntity);
                }
                sysRegionService.saveOrUpdateBatch(sysRegionEntityList);
            }
        }
        log.info("清洗组装耗时毫秒数=【{}】", System.currentTimeMillis() - startTime);
        return "清洗组装树形结构完成！";
    }

    private void updateProperties(Map<String, SysRegionEntity> dataMap, SysRegionEntity sysRegionEntity, String areaCode) {
        if (dataMap.containsKey(areaCode)) {
            SysRegionEntity entity = dataMap.get(areaCode);
            if (!sysRegionEntity.getParentId().equals(entity.getId())) {
                sysRegionEntity.setParentId(entity.getId());
            }
        }
    }

}
